﻿#include "xlabelstring_p.h"

XLabelStringPrivate::XLabelStringPrivate()
    : borderColor(Qt::transparent),
      borderWidth(3),
      borderRadius(5),
      labelBgColor(Qt::transparent),
      displayEnable(true),
      displayDefault(true),
      defaultText("Label"),
      textBuffer(),
      LeftmousePressed(false),
      mousePressPoint(0, 0)
{
    displayString = defaultText;
}

XLabelStringPrivate::~XLabelStringPrivate()
{

}

XLabelString::XLabelString(QWidget *parent, Qt::WindowFlags f)
    : QLabel(parent, f),
      d(new XLabelStringPrivate)
{
    //设置初始默认风格
    //绘制准备工作,启用反锯齿
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);

    QFont font = painter.font();
    font.setFamily("Microsoft YaHei"); //字体

    QTextOption option;
    option.setWrapMode(QTextOption::WordWrap);

    this->setAlignment(Qt::AlignVCenter | Qt::AlignHCenter);

    update();
}

XLabelString::~XLabelString()
{
    delete d;
}

/*!
    \property XLabelString::borderColor
    \brief the color of the border

    The border is the outermost layer of the XLabelString.

    The default border is black.

    \sa indent
*/
QColor XLabelString::getBorderColor() const
{
    return d->borderColor;
}

void XLabelString::setBorderColor(const QColor &color)
{
    if(d->borderColor == color)
        return;
    d->borderColor = color;
    this->update();
}

/*!
    \property XLabelString::borderWidth
    \brief the width of the border

    The border is the outermost layer of the XLabelString.

    The default border is 0.

    \sa indent
*/
int XLabelString::getBorderWidth() const
{
    return d->borderWidth;
}

void XLabelString::setBorderWidth(int borderWid)
{
    if(d->borderWidth == borderWid)
        return;
    d->borderWidth = borderWid;
    this->update();
}

/*!
    \property XLabelString::borderRadius
    \brief the radius of the border

    The border is the outermost layer of the XLabelString.

    The default radius is 0.

    \sa indent
*/
int XLabelString::getBorderRadius() const
{
    return d->borderRadius;
}

void XLabelString::setBorderRadius(int borderRad)
{
    if(d->borderRadius == borderRad)
        return;
    d->borderRadius = borderRad;
    this->update();
}

/*!
    \property XLabelString::labelBgColor
    \brief the color of the labelBackground

    The border is the outermost layer of the XLabelString.

    The default border is transparent.

    \sa indent
*/
QColor XLabelString::getLabelBgColor() const
{
    return d->labelBgColor;
}

void XLabelString::setLabelBgColor(const QColor &color)
{
    if(d->labelBgColor == color)
        return;
    d->labelBgColor = color;
    this->update();
}

/*!
    \property XLabelString::displayString
    \brief the displayString of XLabelString

    True or False corresponds to display or undisplay.

    The default DisplayEnable is true.

    \sa indent
*/
QString XLabelString::getDisplayString() const
{
    return d->displayString;
}

void XLabelString::setDisplayString(QString str)
{
    if(d->displayString == str)
        return;
    d->displayString = str;
    this->update();
}


/*!
    \property XLabelString::displayEnable
    \brief control the XLabelString whether or not display

    True or False corresponds to display or undisplay.

    The default DisplayEnable is true.

    \sa indent
*/
bool XLabelString::getDisplayEnable() const
{
    return d->displayEnable;
}

void XLabelString::setDisplayEnable(bool displayEnabl)
{
    if(d->displayEnable == displayEnabl)
        return;
    d->displayEnable = displayEnabl;

    if(!d->displayEnable)
    {
        d->textBuffer = d->displayString;
        d->displayString = "";
    }
    else
    {
        d->displayString = d->textBuffer;
    }
    this->update();
}

/*!
    \property XLabelString::displayDefault
    \brief control the default text to display

    True or False corresponds to default or notdefault.

    The default displayDefault is true.

    \sa indent
*/
bool XLabelString::getDisplayDefault() const
{
    return d->displayDefault;
}

void XLabelString::setDisplayDefault(bool displayDefau)
{
    if(d->displayDefault == displayDefau)
        return;
    d->displayDefault = displayDefau;

    this->update();
}

/*!
    \reimp
*/
void XLabelString::paintEvent( QPaintEvent *ev)
{
    //绘制准备工作,启用反锯齿
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);

    //绘制边框
    drawBorder(&painter);
    //绘制背景
    drawBg(&painter);

    if(d->displayDefault)
        this->setText(d->defaultText);
    else
        this->setText(d->displayString);

    QLabel::paintEvent(ev);
}

/*!
 * \brief XLabelString::drawBorder
 * \param painter
 */
void XLabelString::drawBorder(QPainter *painter)
{
    painter->save();

    painter->setPen(QPen(d->borderColor, d->borderWidth));
    painter->setBrush(Qt::NoBrush);

    QPointF topLeft(0, 0);
    QPointF bottomRight(width(), height());
    QRectF rect(topLeft, bottomRight);

    painter->drawRoundedRect(rect, d->borderRadius, d->borderRadius);

    painter->restore();
}

/*!
 * \brief XLabelString::drawBg
 * \param painter
 */
void XLabelString::drawBg(QPainter *painter)
{
    painter->save();

    QPointF topLeft(this->margin(), this->margin());
    QPointF bottomRight(width() - this->margin(), height() - this->margin());
    QRectF bgRect(topLeft, bottomRight);
    QBrush bgBrush(d->labelBgColor);
    painter->setPen(Qt::NoPen);
    painter->setBrush(bgBrush);
    painter->drawRoundedRect(bgRect, d->borderRadius/2, d->borderRadius/2);

    painter->restore();
}

/*!
 * \brief XLabelString::enterEvent
 * \param ev
 */
void XLabelString::enterEvent(QEvent *ev)
{
    if(QEvent::Enter == ev->type())
    {
        QCursor cursor;                           //创建光标对象
        cursor.setShape(Qt::PointingHandCursor);  //设置光标形状(指)
        setCursor(cursor);                        //使用光标
    }
}

/*!
 * \brief XLabelString::leaveEvent
 * \param ev
 */
void XLabelString::leaveEvent(QEvent *ev)
{
    if(QEvent::Leave == ev->type())
    {
        QCursor cursor;                           //创建光标对象
        cursor.setShape(Qt::ArrowCursor);         //设置光标形状(箭头)
        setCursor(cursor);                        //使用光标
    }
}

/*!
 * \brief XLabelString::mousePressEvent
 * \param ev
 */
void XLabelString::mousePressEvent(QMouseEvent *ev)
{
    if(Qt::LeftButton == ev->button())
    {
        d->LeftmousePressed = true;
        d->mousePressPoint = ev->globalPos();

        QCursor cursor;                         //创建光标对象
        cursor.setShape(Qt::ClosedHandCursor);  //设置光标形状(抓)
        setCursor(cursor);                      //使用光标
    }
}

/*!
 * \brief XLabelString::mouseReleaseEvent
 * \param ev
 */
void XLabelString::mouseReleaseEvent(QMouseEvent *ev)
{
    if(Qt::LeftButton == ev->button())
    {
        d->LeftmousePressed = false;

        QCursor cursor;                           //创建光标对象
        cursor.setShape(Qt::PointingHandCursor);  //设置光标形状(指)
        setCursor(cursor);                        //使用光标
    }
}

/*!
 * \brief XLabelString::mouseMoveEvent
 * \param ev
 */
void XLabelString::mouseMoveEvent(QMouseEvent *ev)
{
    // 鼠标左键拖动移动
    if(d->LeftmousePressed)
    {
        double mouseDx = ev->globalPos().x() - d->mousePressPoint.x();
        double mouseDy = ev->globalPos().y() - d->mousePressPoint.y();
        d->mousePressPoint = ev->globalPos();

        double myLabelNewx = this->x() + mouseDx;
        double myLabelNewy = this->y() + mouseDy;

        if(myLabelNewx < 0)
            myLabelNewx = 0;
        if(myLabelNewx + this->width() > QApplication::activeWindow()->width())
            myLabelNewx = QApplication::activeWindow()->width() - this->width();
        if(myLabelNewy < 0)
            myLabelNewy = 0;
        if(myLabelNewy + this->height() > QApplication::activeWindow()->height())
            myLabelNewy = QApplication::activeWindow()->height() - this->height();

        move(myLabelNewx, myLabelNewy);
        repaint();
    }
}
